﻿/*基于百度地图JavaScript API GL*/

var regex = /"/gi;
var regexReverse = /msnoshain/gi;
var selectedFeature = null;
var currentInfoWindow = null;
var globalDotNetHelper = null;
var sosPath = null;
var sosStartMarker = null;
var sosEndMarker = null;
var pointIndex = -1;
var globalTravelPoint = null;
var route = null;

/*
 基础地图功能
 */

//添加地图
function addmap() {
    map = new BMapGL.Map("allmap", {
        minZoom: 5,
        maxZoom: 20
    });
    map.centerAndZoom(new BMapGL.Point(125.331, 43.892), 15);
    map.enableScrollWheelZoom(true);
    var scaleCtrl = new BMapGL.ScaleControl();
    map.addControl(scaleCtrl);
    var zoomCtrl = new BMapGL.ZoomControl();
    map.addControl(zoomCtrl);
    var navi3DCtrl = new BMapGL.NavigationControl3D({
        // 控件的停靠位置（可选，默认左上角）
        anchor: BMAP_ANCHOR_BOTTOM_RIGHT,
        // 控件基于停靠位置的偏移量（可选）
        offset: new BMapGL.Size(5, 120)
    });  // 添加3D控件
    map.addControl(navi3DCtrl);
    ///区域限制
    var bound = new BMapGL.Bounds(new BMapGL.Point(124.226288, 43.319491), new BMapGL.Point(126.960515, 44.623687));
    //try {
    //    BMapGLLib.AreaRestriction.setBounds(map, bound);
    //} catch (e) {
    //    alert(e);
    //}
}

//转到地图中心
function gotomapcenter() {
    map.centerAndZoom(new BMapGL.Point(125.331, 43.892), 15);
}

//获取屏幕中心坐标
function getmapcenter() {
    return JSON.stringify(map.getCenter());
}

function getDraftBasicInfo() {
    var center = map.getCenter();
    return JSON.stringify({
        Lng: center.lng,
        Lat: center.lat,
        Zoom: map.getZoom().toFixed(0)
    });
}

//清除图层
function clearlayers() {
    map.clearOverlays();
}

/*
 标绘绘制，量算功能
 */

//点标记功能
function startaddMarker() {
    $("#umarker").show();
    $("#umeasureline").hide();
    $("#umeasurearea").hide();
    map.addEventListener('click', clickAndAddCommonMarkerEvent);
}

//关闭点标记功能
function stopaddMarker() {
    map.removeEventListener('click', clickAndAddCommonMarkerEvent);
    $("#umarker").hide();
}

//距离量算功能
function DistanceMeasure() {
    map.removeEventListener('click');
    $("#umeasureline").show();
    $("#umarker").hide();
    $("#umeasurearea").hide();
    myDis = new BMapGLLib.DistanceTool(map);
    // 监听测距过程中的鼠标事件
    //myDis.addEventListener('drawend', function (e) {

    //});
    //myDis.addEventListener("addpoint", function (e) {

    //});
    //myDis.addEventListener("removepolyline", function (e) {

    //});
    myDis.open();
}

//关闭距离量算功能
function closeDistanceMeasure() {
    myDis.close()
    $("#umeasureline").hide();
}

//面积量算
function activedrawingmanager() {
    map.removeEventListener('click');
    $("#umeasurearea").show();
    $("#umarker").hide();
    $("#umeasureline").hide();
    styleOptions = {
        strokeColor: '#5E87DB',   // 边线颜色
        fillColor: '#5E87DB',     // 填充颜色。当参数为空时，圆形没有填充颜色
        strokeWeight: 2,          // 边线宽度，以像素为单位
        strokeOpacity: 1,         // 边线透明度，取值范围0-1
        fillOpacity: 0.2          // 填充透明度，取值范围0-1
    };
    labelOptions = {
        borderRadius: '2px',
        background: '#FFFBCC',
        border: '1px solid #E1E1E1',
        color: '#703A04',
        fontSize: '12px',
        letterSpacing: '0',
        padding: '5px'
    };
    drawingManager = new BMapGLLib.DrawingManager(map, {
        enableCalculate: true,  // 绘制是否进行测距测面
        enableSorption: true,   // 是否开启边界吸附功能
        sorptiondistance: 20,   // 边界吸附距离
        enableGpc: true,        // 是否开启延边裁剪功能
        enableLimit: true,      // 是否开启超限提示
        limitOptions: {
            area: 5000000000,     // 面积超限值
            distance: 3000000     // 距离超限值
        },
        circleOptions: styleOptions,     // 圆的样式
        polylineOptions: styleOptions,   // 线的样式
        polygonOptions: styleOptions,    // 多边形的样式
        rectangleOptions: styleOptions,  // 矩形的样式
        labelOptions: labelOptions,      // label样式
    });
}

//关闭面积量算功能
function closemeasurearea() {
    $("#umeasurearea").hide();
}

function draw(shape) {
    switch (shape) {
        case 'marker': {
            var drawingType = BMAP_DRAWING_MARKER;
            break;
        }
        case 'polyline': {
            var drawingType = BMAP_DRAWING_POLYLINE;
            break;
        }
        case 'rectangle': {
            var drawingType = BMAP_DRAWING_RECTANGLE;
            break;
        }
        case 'polygon': {
            var drawingType = BMAP_DRAWING_POLYGON;
            break;
        }
        case 'circle': {
            var drawingType = BMAP_DRAWING_CIRCLE;
            break;
        }
    }
    // 进行绘制
    if (drawingManager._isOpen && drawingManager.getDrawingMode() === drawingType) {
        drawingManager.close();
    } else {
        drawingManager.setDrawingMode(drawingType);
        drawingManager.open();
    }
    // 绘制完成后获取相关的信息(面积等)
    drawingManager.addEventListener('overlaycomplete', function (e) {
        e.overlay.addEventListener('click', clickOverlayEvent);
    });
};

//单击覆盖物事件
function clickOverlayEvent(e) {
    selectedFeature = e.currentTarget;
    var p = e.target;
    if (p instanceof BMapGL.Circle) {
        var center = new BMapGL.Point(p.getCenter().lng, p.getCenter().lat);
        drawcirclecenter = center;
        drawcircleradius = Number(p.getRadius());
        currentInfoWindow = new BMapGL.InfoWindow(
            getCircleindowInfoString(drawcircleradius, drawcirclecenter),
            getWindowOpts('圆形区域'));
        map.openInfoWindow(currentInfoWindow, center);
        map.centerAndZoom(center, 14);
        return;
    }
    if (p instanceof BMapGL.Polygon) {
        if (p.points.length == 5 && p.points[0].latLng.lat == p.points[1].latLng.lat && p.points[1].latLng.lng == p.points[2].latLng.lng && p.points[2].latLng.lat == p.points[3].latLng.lat) {
            var clng = (p.points[0].latLng.lng + p.points[1].latLng.lng) / 2;
            var clat = (p.points[1].latLng.lat + p.points[2].latLng.lat) / 2;
            var center = new BMapGL.Point(clng, clat);
            //半正矢公式算法(有误差)，但是在小面积的时候就(合理怀疑百度API在小面积的时候是瞎算)
            var R = 6371 * Math.cos(46.12 * 180 / Math.PI);
            var dlat1 = Math.abs(degtorad(p.points[2].latLng.lat - p.points[1].latLng.lat));
            var dlng2 = Math.abs(degtorad(p.points[1].latLng.lng - p.points[0].latLng.lng));
            var a1 = Math.sin(dlat1 / 2) * Math.sin(dlat1 / 2);
            var a2 = Math.sin(dlng2 / 2) * Math.sin(dlng2 / 2) * Math.cos(degtorad(p.points[1].latLng.lat) * Math.cos(p.points[0].latLng.lat));
            var c1 = 2 * Math.asin(Math.sqrt(a1));
            var c2 = 2 * Math.asin(Math.sqrt(a2));
            var d1 = R * c1 * 1000, d2 = R * c2 * 1000;
            var area = d1 * d2;
            //半正矢公式计算面积区域结束
            //矩形检索范围
            var pStart = new BMapGL.Point(p.points[3].latLng.lng, p.points[3].latLng.lat);
            var pEnd = new BMapGL.Point(p.points[1].latLng.lng, p.points[1].latLng.lat);
            bs = new BMapGL.Bounds(pStart, pEnd);
            var nsContent = getRectangularWindowInfoString(area, pStart, pEnd);
            currentInfoWindow = new BMapGL.InfoWindow(nsContent, getWindowOpts('矩形区域'));
            map.openInfoWindow(currentInfoWindow, center);
            map.centerAndZoom(center, 14);
        }
        return;
    }
    alert('无法获知该覆盖物类型');
}

//转化为弧度
function degtorad(deg) {
    return deg * (Math.PI / 180);
}

//圆形检索
function circlesearch(center, radius) {
    var searchstring = $("#icirclesearch").val();
    var local = new BMapGL.LocalSearch(map, { renderOptions: { map: map, autoViewport: false } });
    local.searchNearby(searchstring, center, radius);
}

//矩形检索
function polygonsearch(area) {
    var searchp = $("#ipolygonsearch").val();
    console.log(searchp);
    console.log(bs);
    var local = new BMapGL.LocalSearch(map, {
        renderOptions: { map: map }
    });
    local.searchInBounds(searchp, area);
}

/*
 通用事件
 */

//设置dotNetHelper
function setDotNetHelper(dotNetHelper) {
    globalDotNetHelper = dotNetHelper;
}

//单击添加普通点标记事件
function clickAndAddCommonMarkerEvent(e) {
    var point = new BMapGL.Point(e.latlng.lng, e.latlng.lat);
    var marker = new BMapGL.Marker(point);

    marker.addEventListener('click', async function (e) {
        selectedFeature = e.currentTarget;
        var posinfo = e.latLng;
        var address = await globalDotNetHelper.invokeMethodAsync("PointDecode", JSON.stringify(point));
        globalTravelPoint = {
            Address: address,
            Position: point,
        }
        currentInfoWindow = new BMapGL.InfoWindow(getCommonPointInfoWindowString(address), getWindowOpts('地点'));
        map.openInfoWindow(currentInfoWindow, posinfo);
    });
    map.addOverlay(marker);
}

//移除所选要素
function clearselectedfeature() {
    if (selectedFeature != null) {
        currentInfoWindow.hide();
        map.removeOverlay(selectedFeature);
    }
}

//设置起点
function msetstartpoint() {
    if (globalTravelPoint != null)
        globalDotNetHelper.invokeMethodAsync("SetStartPoint", JSON.stringify(globalTravelPoint));
}

//设置终点
function msetendpoint() {
    if (globalTravelPoint != null)
        globalDotNetHelper.invokeMethodAsync("SetEndPoint", JSON.stringify(globalTravelPoint));
}

//添加路径
function addPath(path, style = null) {
    var points = new Array(path.length + 1);
    for (var i = 0; i < points.length - 1; i++) {
        points[i] = new BMapGL.Point(path[i].start_location.lng, path[i].start_location.lat);
    }
    var lastpoint = path[path.length - 1].end_location;
    points[path.length] = new BMapGL.Point(lastpoint.lng, lastpoint.lat);
    if (style == null)
        var p = new BMapGL.Polyline(points, { strokeColor: "blue", strokeWeight: 6, strokeOpacity: 1 });
    else
        var p = new BMapGL.Polyline(points, style);
    map.addOverlay(p);
    return p;
}

async function queryWeather() {
    globalDotNetHelper.invokeMethodAsync("QueryWeather", JSON.stringify(selectedFeature.latLng));
}

/*
 弹窗样式字符串
 */

function getWindowOpts(title = '') {
    return opts = {
        width: 400,
        title: '<div style="color:#fff;margin:0px 0px;background-color: #4DB6AC;">' + title + '</div>',
        message: "result"
    }
}

//获取Poi信息窗字符串
function getPoiInfoWindowString(name, address, tel) {
    return '<div class="clearfix">' + '<div class="box">' +
        '<div style="margin:5px 20px;font-size: 16px;weight:75%">' + "地址：" + address + '</div>' +
        '<div style="margin:5px 20px;font-size: 16px;">' + "电话：" + (tel == null ? '暂无' : tel) + '</div>' +
        '<a style="text-align: center;margin:15px" target="_blank" href=' + "https://www.baidu.com/s?ie=UTF-8&wd=" + name + '>详情</a>' + '</div > ' +
        '<div class="box"><img id="imgDemo" src="../cc.jpeg" alt="" style="float:right;zoom:1;overflow:hidden;width:160px;height:90px;margin-left:3px;"/>' + '</div ></div> ' +
        '<div style="text-align: center;bottom: 16px">' +
        '<button class="infobtn" onclick="msetstartpoint()" style="border-radius:5px">设为起点</button>' +
        '<button class="infobtn" onclick="msetendpoint()" style="border-radius:5px">设为终点</button>' +
        '<button class="infobtn" onclick="clearselectedfeature()" style="border-radius:5px">删除标记</button >' + '</div>' +
        '<span style="visibility:hidden;">&nbsp;spacer</span>';
}

//获取普通标记信息窗字符串
function getCommonPointInfoWindowString(address) {
    return '<div class="clearfix">' +
        '<div style="margin:5px 20px;font-size: 16px;weight:75%">' + "地址：" + address + '</div>' + '</div> ' +
        '<span style="visibility:hidden;">&nbsp;spacer</span>' +
        '<span style="visibility:hidden;">&nbsp;spacer</span>' +
        '<div style="text-align: center;bottom: 16px">' +
        '<button class="infobtn" onclick="msetstartpoint()" style="border-radius:5px">设为起点</button>' +
        '<button class="infobtn" onclick="msetendpoint()" style="border-radius:5px">设为终点</button>' +
        '<button class="infobtn" onclick="clearselectedfeature()" style="border-radius:5px">移除标记</button >' +
        '<button class="infobtn" onclick="queryWeather()" style="border-radius:5px">查询天气</button >' +
        '</div>' +
        '<span style="visibility:hidden;">&nbsp;spacer</span>';
}

//获取救援点信息窗字符串
function getSosPointInfoWindowString(distance, duration, address, name, tel) {
    return '<div class="clearfix" style="width:300px !important;">' +
        '<div style="margin:7px 20px;font-size: 16px;width:100%">' + "推荐医院：" + name + '</div>' +
        '<div style="margin:7px 20px;font-size: 16px;width:100%">' + "联系电话：" + (tel == null ? '暂无' : tel) + '</div>' +
        '<div style="margin:7px 20px;font-size: 16px;width:100%">' + "预计里程：" + (distance / 1000).toFixed(2) + ' 公里' + '</div>' +
        '<div style="margin:7px 20px;font-size: 16px;width:100%">' + "预计耗时：约 " + (duration / 60).toFixed(0) + ' 分钟' + '</div>' +
        '<span style="visibility:hidden;">&nbsp;spacer</span>' +
        '<div style="margin:7px 20px;font-size: 14px;width:100%;color:gray">' + "地址：" + address + '</div>' +
        '</div > ' + '<span style="visibility:hidden;">&nbsp;spacer</span>';
}

//获取矩形信息窗字符串
function getRectangularWindowInfoString(area, pStart, pEnd) {
    return '<div style="margin:5px 20px;font-size: 16px;">' + "面积：" + area + "平方米" + '</div>' +
        '<div style="margin:5px 20px;font-size: 14px;">' + "左上坐标：经度 " + pStart.lng.toFixed(2) + '，纬度 ' + pStart.lat.toFixed(2) + '</div>' +
        '<div style="margin:5px 20px;font-size: 14px;">' + "右下坐标：经度 " + pEnd.lng.toFixed(2) + '，纬度 ' + pEnd.lat.toFixed(2) + '</div>' +
        '<div style="margin:5px 20px;font-size: 16px;text-align: center;">' + '<input type="text" id="ipolygonsearch" placeholder="请输入关键词">' +
        '<button class="infobtn" onclick="polygonsearch(bs)" style="margin-left:16px;border-radius:5px">查询</button >' + 
        '<div style="height:18px"></div>' +
        '<button class="infobtn" style="border-radius:5px" onclick="clearselectedfeature()">移除覆盖物</button >' + '</div>' +
        '<span style="visibility:hidden;">&nbsp;spacer</span>';
}

function getCircleindowInfoString(radius, center) {
    return '<div style="margin:5px 20px;font-size: 16px;">' + "面积：" + (radius * radius * 3.1415926535).toFixed(2) + "平方米" + '</div>' +
        '<div style="margin:5px 20px;font-size: 16px;">' + "半径：" + radius.toFixed(2) + "米" + '</div>' +
        '<div style="margin:5px 20px;font-size: 16px;">' + "圆心：经度 " + center.lng.toFixed(2) + '，纬度 ' + center.lat.toFixed(2) + '</div>' +
        '<div style="margin:5px 20px;font-size: 16px;text-align: center;top:10px">' +
        '<input type="text" id="icirclesearch" placeholder="请输入关键词">' +
        '<button class="infobtn" onclick=" circlesearch(center,radius) style="margin-left:16px;border-radius:5px">查询</button >' +
        '<div style="height:18px"></div>'+
        '<button class="infobtn" style="border-radius:5px" onclick="clearselectedfeature()">移除覆盖物</button >' + '</div>' +
        '<span style="visibility:hidden;">&nbsp;spacer</span>';
}

/*
 Poi搜索
 */

//添加单个Poi标记，并绑定弹窗
function addSingleMarker(poiRsultJson) {
    var poi = JSON.parse(poiRsultJson);
    var point = new BMapGL.Point(poi.location.lng, poi.location.lat);
    var marker = new BMapGL.Marker(point);
    var opts = {
        width: 400,
        title: '<div style="color:#fff;margin:0px 0px;background-color: #4DB6AC;">' + poi.name + '</div>',
        message: "result"
    }
    marker.addEventListener('click', function (e) {
        selectedFeature = e.currentTarget;
        var posinfo = e.latLng;
        currentInfoWindow = new BMapGL.InfoWindow(getPoiInfoWindowString(poi.name, poi.address, poi.telephone), opts);
        map.openInfoWindow(currentInfoWindow, posinfo);
    });
    map.addOverlay(marker);
    map.centerAndZoom(point, 14);
}

//神秘代码，勿删：' + "'" + JSON.stringify(posinfo).replace(regex, 'msnoshain') + "'" + '

/*
 路况查询
 */
function trafficlayer() {
    count++;
    if (count % 2 == 0) {
        map.setTrafficOn();
    }
    if (count % 2 != 0) {
        map.setTrafficOff();
    }
}

/*
 救援查询
 */

//单击添加事故点事件
async function addSosPointEvent(e) {
    var result = e.latlng;
    var point = new BMapGL.Point(result.lng, result.lat);
    sosStartMarker = new BMapGL.Marker(point);
    map.removeEventListener('click', addSosPointEvent);
    map.addOverlay(sosStartMarker);
    return await globalDotNetHelper.invokeMethodAsync('SearchSosInfo', JSON.stringify(point));
}

//选择事故点
async function selectsospoint() {
    map.addEventListener('click', addSosPointEvent);
}

//退出救援点查询
function cancelselectsospoint() {
    map.removeEventListener('click', addSosPointEvent);
    if (sosStartMarker != null)
        map.removeOverlay(sosStartMarker);
    if (sosEndMarker != null)
        map.removeOverlay(sosEndMarker);
    if (sosPath != null)
        map.removeOverlay(sosPath);
    if (currentInfoWindow != null)
        currentInfoWindow.hide();
}

//添加救援信息相关要素
function addSosFeature(infoJson) {
    var info = JSON.parse(infoJson);
    var path = info.Route;
    sosPath = addPath(path, { strokeColor: "#C7002D", strokeWeight: 8, strokeOpacity: 1 });
    sosEndMarker = new BMapGL.Marker(path[path.length - 1].end_location);
    sosEndMarker.addEventListener('click', async function (e) {
        selectedFeature = e.currentTarget;
        var posinfo = e.latLng;
        currentInfoWindow = new BMapGL.InfoWindow(
            getSosPointInfoWindowString(info.Distance, info.Duration, info.Address, info.Name, info.Tel),
            getWindowOpts('推荐救援点'));
        map.openInfoWindow(currentInfoWindow, posinfo);
    });
    map.addOverlay(sosEndMarker);
    map.centerAndZoom(path[path.length - 1].end_location, 15);
}

/*
 路径规划
 */

async function addTravelPoint(e) {
    map.removeEventListener('click', addTravelPoint);
    var point = new BMapGL.Point(e.latlng.lng, e.latlng.lat);
    var marker = new BMapGL.Marker(point);
    var address = await globalDotNetHelper.invokeMethodAsync("PointDecode", JSON.stringify(point));

    marker.addEventListener('click', async function (e) {
        selectedFeature = e.currentTarget;
        var posinfo = e.latLng;
        globalTravelPoint = {
            Address: address,
            Position: point,
        }
        currentInfoWindow = new BMapGL.InfoWindow(
            getCommonPointInfoWindowString(address),
            getWindowOpts('地点'));
        map.openInfoWindow(currentInfoWindow, posinfo);
    });
    map.addOverlay(marker);

    var infoJson = JSON.stringify({
        Address: address,
        Position: point,
    });

    if (pointIndex == 0) {
        await globalDotNetHelper.invokeMethodAsync("SetStartPoint", infoJson);
        return;
    }
    if (pointIndex == 1) {
        await globalDotNetHelper.invokeMethodAsync("SetEndPoint", infoJson);
        return;
    }
    if (pointIndex == 2) {
        await globalDotNetHelper.invokeMethodAsync("AddTravelPoint", infoJson);
        return;
    }
}

async function selectTravelPoint(index) {
    pointIndex = index;
    map.addEventListener("click", addTravelPoint);
}

/*
地图标绘
 */

async function addAnnotations(infoJson) {
    var annos = JSON.parse(infoJson);

    map.centerAndZoom(new BMapGL.Point(annos.Lng, annos.Lat), annos.Zoom);

    annos.Points.forEach(function (item) {
        map.addOverlay(new BMapGL.Marker(new BMapGL.Point(item.lng, item.lat)));
    });

    annos.Polylines.forEach(function (item) {
        var pts = [];
        item.forEach(function (item1) { pts.push(new BMapGL.Point(item1.lng, item1.lat)); })
        map.addOverlay(new BMapGL.Polyline(pts, {
            strokeColor: "blue",
            strokeWeight: 4,
            strokeOpacity: 1
        }));
    });

    annos.Polygons.forEach(function (item) {
        var pts = [];
        item.forEach(function (item1) { pts.push(new BMapGL.Point(item1.lng, item1.lat)); })
        map.addOverlay(new BMapGL.Polygon(pts, {
            strokeColor: "blue",
            strokeWeight: 3,
            strokeOpacity: 1,
            fillColor: "blue",
            fillOpacity: 0.1
        }));
    });

}

async function collectAnnotations() {
    var overlays = map.getOverlays();
    var pts = [];
    var plgs = [];
    var plls = [];
    overlays.forEach(function (item) {
        if (item instanceof BMapGL.Polygon) {
            var path = item.getPath();
            path.push(path[0]);
            plgs.push(path);
            return;
        }

        if (item instanceof BMapGL.Marker) {
            pts.push(item.latLng);
            return;
        }

        if (item instanceof BMapGL.Polyline) {
            plls.push(item.getPath());
            return;
        }
    })

    return JSON.stringify({
        Points: pts,
        Polylines: plls,
        Polygons: plgs
    });
}

//坐标转换函数
//BD09转GCJ02
function BD_GCJ(x, y) {
    var ggPoint = new BMapGL.Point(x, y);

    //坐标转换完之后的回调函数
    translateCallback = function (data) {
        console.log(data);
        console.log(data.points[0].lat);
    }

    setTimeout(function () {
        var convertor = new BMapGL.Convertor();
        var pointArr = [];
        pointArr.push(ggPoint);
        convertor.translate(pointArr, 5, 3, translateCallback)
    }, 100);
}